<?php
/*
 * File: Order.php
 * Project: NewDemo
 * Created Time: 2024-07-15 03:16:47 pm
 * Author: WangYuQiang && WangpeiGang (719404171@qq.com)
 * -----
 * Last Modified: 2025-07-21 2:32:28 pm
 * Modified By: WangYuQiang (719404171@qq.com>)
 * -----
 * Copyright (c) 2023 - 2024 成都睿創科技有限公司
 */



namespace App\Models;

use DateTimeInterface;
use App\Models\Base;
use App\Http\Controllers\Api\MailController;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Auth\User as Authenticatable;

/**
 * App\Models\Order
 */
class Order extends Base{

    use Notifiable;
    public $timestamps = true;
    protected $table = 'order';

    /**
     * 为数组 / JSON 序列化准备日期。
     */
    protected function serializeDate(DateTimeInterface $date){
        return $date->format($this->dateFormat ?: 'Y-m-d H:i:s');
    }

    /**
     * 關聯訂單詳情表
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function OrderDetails(){
        return $this->hasMany('App\Models\OrderDetails', 'order_id', 'order_id');
    }

    /**
     * 函數構造
     */
    public function __construct(){
        $this->language = app('global_language') == "en" ? "en_" : "";
    }




/*********************************************************全局作用域注册**********************************************************************/
    protected static function boot(){
       parent::boot();
	   static::addGlobalScope('order', function (Builder $builder) {
		  return $builder->where('order.order_status', '<>', -1);
	   });
    }

/*********************************************************admin**************************************************************************/

    /**
     * 獲取訂單列表
     * @param $data
     * @return mixed
     */
    public function getOrderListWeb($data){
        $limit = $data['limit'];
        $page =  ( $data['page'] - 1 ) * $limit;
        $time = [];
        $where[] = array('order.order_status', '<>', -1);
        $where[] = array('users.user_status', '<>', -1);
        if (!empty($data['delivery_area'])) {
            $where[] = array('order.delivery_area', 'like', '%' . $data['delivery_area'] . '%');
        }
        if(!empty($data['payment_status'])){
            $where['order.payment_status'] = $data['payment_status'];
        }
        if(!empty($data['time'])){
            $time['start_time'] = $data['time'][0];
            $time['end_time'] = $data['time'][1];
        }
        OrderDetails::$modify = true;
        $datas['data'] = $this->with(['OrderDetails'=>function($query){
            $query->with('OrderLogistics');
        }])
            ->join('users','users.user_id','=','order.user_id')
            ->where($where)
            ->whereIn('order.indent_type',$data['indent_type'])
            ->where(function ($query) use ($time){
                if(!empty($time) && $time['start_time'] != ''){
                    return $query->whereBetween('order.payment_at',$time);
                }
            })
            ->select('order.*')
            ->offset($page)->limit($limit)
            ->orderBy('order.created_at', 'desc')
            ->get()->toArray();
        $datas['count'] = $this->join('users','users.user_id','=','order.user_id')
            ->where($where)
            ->whereIn('order.indent_type',$data['indent_type'])
            ->where(function ($query) use ($time){
                if(!empty($time) && $time['start_time'] != ''){
                    return $query->whereBetween('order.payment_at',$time);
                }
            })->count();
        $money = $this->getGoodsSale($data['indent_type'], $time);//獲取訂單銷售額
        $datas['total_money'] = $money['total_money'];
        $datas['day_money'] = $money['day_money'];
        $datas['month_money'] = $money['month_money'];
        return $datas;
    }

    /**
     * 獲取訂單銷售額
     * @param $type
     * @param $time
     * @return mixed
     */
    public function getGoodsSale($type,$time){
        $data['total_money'] = Order::join('users','order.user_id','=','users.user_id')
            ->whereIn('order.indent_type',$type)
            ->where('order.order_status','<>',-1)
            ->where('order.payment_status','>',2)
            ->where('users.user_status','<>',-1)
            ->where(function ($query) use ($time){
                if(!empty($time) && $time['start_time'] != ''){
                    return $query->whereBetween('order.payment_at',$time);
                }
            })
            ->sum('order.order_money');

        $day_time['start_time'] = date('Y-m-d 00:00:00');
        $day_time['end_time'] = date('Y-m-d 23:59:59');
        $data['day_money'] = Order::join('users','order.user_id','=','users.user_id')
            ->where('order.order_status','<>',-1)
            ->where('order.payment_status','>',2)
            ->where('users.user_status','<>',-1)
            ->whereIn('order.indent_type',$type)
            ->where(function ($query) use ($day_time){
                return $query->whereBetween('order.payment_at',$day_time);
            })
            ->sum('order.order_money');

        $month_time['start_time'] = date('Y-m-01 00:00:00' ,  strtotime('this month'));
        $month_time['end_time'] = date('Y-m-t 23:59:59',  strtotime('this month'));
        $data['month_money'] = Order::join('users','order.user_id','=','users.user_id')
            ->where('order.order_status','<>',-1)
            ->where('order.payment_status','>',2)
            ->where('users.user_status','<>',-1)
            ->whereIn('order.indent_type',$type)
            ->where(function ($query) use ($month_time){
                return $query->whereBetween('order.payment_at',$month_time);
            })
            ->sum('order.order_money');
        return $data;
    }

    /**
     * 修改预约时间
     * @param $data
     * @return array
     */
    public function editOrderTimeWeb($data,$token){
        $admin = Admins::where('token',$token)->select('admin_id','username')->first();
        $update = $this->where('order_id',$data['order_id'])->update(['order_time'=>$data['order_time']]);
        if($update){
            $info = $this->where('order_id',$data['order_id'])->select('order_no','delivery_mail','user_id')->first();
            $cn_content = '訂單：'.$info['order_no'].',預約時間改變！';
            $en_content = 'Order：'.$info['order_no'].',Reservation Time Change！';
            if($this->language == "en" ){
                $languagenow = 'en';//英文模式
                $EmailInfo['Message']=$en_content;
                @self::pushOrderMessage($data['order_id'],$cn_content,$en_content,$languagenow);
            }else{
                $languagenow = 'cn';
                $EmailInfo['Message']=$cn_content;
                @self::pushOrderMessage($data['order_id'],$cn_content,$en_content,$languagenow);
            }
            $this->OrderMessage( $info['user_id'] ,$cn_content , $en_content );
            $email=new MailController();
            $EmailInfo['Email']=$info['delivery_mail'];
            $email->MessageEmails($EmailInfo);
            $editInfo = [//增加訂單操作日誌
                'admin_name' => $admin['username'],
                'admin_id' => $admin['admin_id'],
                'order_id' => $data['order_id'],
                'activity_type' => 6,//修改預約時間
                'activity_value' => $cn_content,
                'en_activity_value' => $en_content,
                'created_at' =>  self::getDate()
            ];
            $editInsert = ActivityLog::insert($editInfo);
            if($editInsert){
                return $this->success(__('web.edit_success'));
            }else{
                return $this->error(__('web.activitylog_fail'));
            }
        }else{
            return $this->error(__('web.edit_fail'));
        }
    }

    /**
     * 修改订单支付时间(修改订单支付時間/与订单详情同步)
     * @param $datas
     * @return array
     */
    public function editPaymentTime($datas){
        DB::beginTransaction();
        if (!empty($datas['order_id']) || !empty($datas['payment_at'])) {
            Order::where('order_id', $datas['order_id'])->update(['payment_at' => $datas['payment_at']]);
            DB::commit();
            return $this->success(__('web.edit_success'));
        } else {
            DB::rollBack();
            return $this->error(__('web.edit_fail'));
        }
    }


    /**
     * 确认支付
     * @param $orderID
     * @return array
     */
    public function confirmPaymentWeb($orderID,$token){
        $admin = Admins::where('token',$token)->select('admin_id','username')->first();
        $data = $this->where('order_id',$orderID)->update(['payment_status'=>3,'payment_at'=>self::getDate()]);
        if($data){
            $info = $this->where('order_id',$orderID)->select('order_no','user_id','delivery_mail')->first();
            $cn_content = '訂單：'.$info['order_no'].',已完成支付！';
            $en_content = 'Order：'.$info['order_no'].',has completed payment！';
            if($this->language == "en" ){
                $languagenow = 'en';//英文模式
                $EmailInfo['Message']=$en_content;
                @self::pushOrderMessage($data['order_id'],$cn_content,$en_content,$languagenow);
            }else{
                $languagenow = 'cn';
                $EmailInfo['Message']=$cn_content;
                @self::pushOrderMessage($data['order_id'],$cn_content,$en_content,$languagenow);
            }
            $this->OrderMessage( $info['user_id'] ,$cn_content , $en_content );
            $email=new MailController();
            $EmailInfo['Email']=$info['delivery_mail'];
            $email->MessageEmails($EmailInfo);
            $configInfo = [//增加訂單操作日誌
                'admin_name' => $admin['username'],
                'admin_id' => $admin['admin_id'],
                'order_id' => $orderID,
                'activity_type' => 7,//確認訂單支付
                'activity_value' => $cn_content,
                'en_activity_value' => $en_content,
                'created_at' =>  self::getDate()
            ];
            $configInsert = ActivityLog::insert($configInfo);
            if($configInsert){
                return $this->success(__('web.edit_success'));
            }else{
                return $this->error(__('web.activitylog_fail'));
            }
        }else{
            return $this->error(__('web.edit_fail'));
        }
    }


    /**
     * 刪除訂單
     * @param $orderID
     * @return array
     */
    public function deleteOrderWeb($orderID,$token){
        DB::beginTransaction();
        $admin = Admins::where('token',$token)->select('admin_id','username')->first();
        $updateDetails = OrderDetails::where('order_id',$orderID)->update(['details_status' => '-1']);
        $updateOrder = $this->where('order_id',$orderID)->update(['order_status'=>-1]);
        $orderIDs = is_array($orderID) ? $orderID : [$orderID];
        $orders = $this->whereIn('order_id', $orderIDs)->select('order_id', 'order_no')->get();
        // 准备日志数据
        $configInfo = [];
        $currentTime = self::getDate();
        foreach ($orders as $order) {
            $content = '訂單：'.$order['order_no'].',已刪除！';
            $en_content ='Order：'.$order['order_no'].',has been deleted！';

            $configInfo[] = [
                'admin_name' => $admin['username'],
                'admin_id' => $admin['admin_id'],
                'order_id' => $order['order_id'],
                'activity_type' => 9,//刪除訂單
                'activity_value' => $content,
                'en_activity_value' => $en_content,
                'created_at' =>  $currentTime
            ];
        }
        $configInsert = ActivityLog::insert($configInfo);
        if($updateDetails && $updateOrder && $configInsert) {
            DB::commit();
            return $this->success(__('web.delete_success'));
        }else{
            DB::rollBack();
            return $this->error(__('web.delete_fail'));
        }
    }

    /**
     * 獲取日曆訂單
     * @param $data
     * @return mixed
     */
    public function getCalendarOrdersWeb($data){
        $where[] = array('order_details.details_status','=',1);
        $where[] = array('users.user_status','=',1);
        $datas = $this->join('order_details', 'order_details.order_id', '=', 'order.order_id')
            ->join('product', 'order_details.product_id', '=', 'product.product_id')
            ->join('users', 'order_details.user_id', '=', 'users.user_id')
            ->whereIn('order.indent_type', $data['indent_type'])//訂單類型  1產品訂單  2預約訂單
            ->where($where)
            ->select('order.order_id','order.order_no','order.created_at','order.updated_at','order.order_time')
            ->orderBy('order.updated_at', 'desc')
            ->get()->toArray();
        return $datas;
    }

    /**
     * 添加線下訂單
     * @param $data
     * @return array
     */
    public function addOfflineOrdersWeb($data){
        DB::beginTransaction();
        $order = [
            'user_id' => $data[0]['user_id'],   //用戶id
            'order_no' =>  self::getOrderNumber(),  //訂單號
            'order_money' => $data[0]['order_money'],   //訂單支付金額
            'original_cost' => $data[0]['original_cost'],   //訂單原价
            'delivery_address' => '線下訂單',   //收货地址-地址
            'delivery_area' => '線下訂單',  //收货地址-区域
            'delivery_name' => '線下訂單',  //收货地址-姓名
            'delivery_phone' => '線下訂單', //收货地址-电话
            'delivery_mail' => '線下訂單',  //收货地址-邮件
            'payment_type' => 1,    //支付类型：1：立即支付，2：預約到店查看
            'payment_mode' => 5,    //支付方式 1：paypal  2：Stripe，3：錢包 ，4：其他支付（上傳支付圖片）5：線下支付
            'order_type' => 2,  //訂單類型：1：線上訂單，2：線下訂單
            'indent_type' =>$data[0]['product_type'],   //訂單類型  1產品訂單  2預約訂單
            'order_time' =>empty($data[0]['order_time']) ? '': $data[0]['order_time'],   //訂單類型  1產品訂單  2預約訂單
            'receiving_type' => 3,  //取货方式：1：商家发货，2：自取
            'payment_at' =>  self::getDate(),   //支付成功時間
            'created_at' =>  self::getDate(),
            'updated_at' =>  self::getDate()
        ];
		if ($data[0]['product_type']==2) {
            $order['payment_status'] = 3;  //支付状态：1：待支付  2：待核验（其他支付的）   3：已支付  4：已取消  5：已完成
        }else{
            $order['payment_status'] = 5;  //支付状态：1：待支付  2：待核验（其他支付的）   3：已支付  4：已取消  5：已完成
        }
        $orderID = $this->insertGetId($order);
        if(!empty($orderID)){
            $addDetails = true;
            for($i=0;$i<count($data);$i++){
                $product_specs[$i] = [];
                $productRelation = true;
                $product = true;
                if(!empty($data[$i]['product_relation_id'])){
                    $product_specs_value_id=ProductRelation::where('product_relation_id',$data[$i]['product_relation_id'])->first()['product_specs_value_id'];
                    $product_specs[$i] = ProductSpecsValue::whereIn('product_specs_value_id',explode('-',$product_specs_value_id))->get()->toArray();
                    if($data[$i]['product_type'] == 1){
                        $productRelation = ProductRelation::where('product_relation_id',$data[$i]['product_relation_id'])->decrement('stock',$data[$i]['product_number']);
                    }
                }
                $detailsInfo[$i] = [
                    'order_id' => $orderID,
                    'user_id' => $data[$i]['user_id'],
                    'product_id' => $data[$i]['product_id'],
                    'product_relation_id' => $data[$i]['product_relation_id'],
                    'product_specs' => json_encode($product_specs[$i]),
                    'product_name' => $data[$i]['product_name'],
                    'product_img' => $data[$i]['product_img'],
                    'product_number' => $data[$i]['product_number'],
                    'product_price' => $data[$i]['product_price'],
                    'product_money' => $data[$i]['product_money'],
                    'product_type' => $data[$i]['product_type'],
                    'logistics_status' => 2,
                    'created_at' => self::getDate(),
                    'updated_at' => self::getDate()
                ];
                $details = OrderDetails::insertGetId($detailsInfo[$i]);
                if($data[$i]['product_type'] == 1){
                    $product = Product::where('product_id',$data[$i]['product_id'])->decrement('product_stock',$data[$i]['product_number']);
                }
                //添加訂單詳情快照-begin
                $Snapshot['details_id']=$details;
                $Coupon=new Coupon;
                $Product=new Product;
                $Snapshot['product_snapshot']=$Product->ProductSnapshot($data[$i]['product_id']);
                $User=new User;
                $Snapshot['user_snapshot']=$User->UserSnapshot($data[$i]['user_id']);
                $OrderSnapshot=new OrderSnapshot;
                $SnapshotInfo=$OrderSnapshot->addOrderSnapshot($Snapshot);
                //添加訂單詳情快照-end
                if( empty($details) || !$product || !$productRelation){
                    $addDetails = false;
                    break;
                }
            }
            if($addDetails){
                DB::commit();
                return $this->success(__('web.add_success'));
            }else{
                DB::rollBack();
                return $this->error(__('web.add_fail'));
            }
        }else{
            DB::rollBack();
            return $this->error(__('web.add_fail'));
        }
    }

    /**
     * web創建訂單
     * @param $data
     * @return array
     */
    public function WebAddOrder($data){
        DB::beginTransaction();
        $order = [
            'user_id' => $data[0]['user_id'],   //用戶id
            'order_no' =>  self::getOrderNumber(),  //訂單號
            'order_money' => $data[0]['order_money'],   //訂單支付金額
            'original_cost' => $data[0]['original_cost'],   //訂單原价
            'delivery_address' => $data[0]['delivery_address'],   //delivery_address收货地址-地址--非必要
            'delivery_area' => $data[0]['delivery_area'],  //delivery_area收货区域--非必要
            'delivery_name' => $data[0]['delivery_name'],  //delivery_name收货姓名--非必要
            'delivery_phone' => $data[0]['delivery_phone'], //delivery_phone收货电话--非必要
            'delivery_mail' => $data[0]['delivery_mail'],  //delivery_mail收货邮件--非必要
            'payment_type' => $data[0]['payment_type'],    //payment_type支付类型：1：立即支付，2：預約到店查看--必要
            'payment_mode' => $data[0]['payment_mode'],    //payment_mode支付方式 1：paypal  2：Stripe，3：錢包 ，4：其他支付（上傳支付圖片）5：線下支付--必要
            'order_type' => $data[0]['order_type'],  //order_type訂單類型：1：線上訂單，2：線下訂單--必要
            'order_time' => $data[0]['order_time'],  //order_time預約時間
            'indent_type' =>$data[0]['product_type'],   //訂單類型  1產品訂單  2預約訂單
            'receiving_type' => $data[0]['receiving_type'],  //receiving_type取货方式：1：商家发货，2：自取--必要
            'payment_status' => $data[0]['payment_status'],  //payment_status支付状态：1：待支付  2：待核验（其他支付的）   3：已支付  4：已取消  5：已完成--必要
            'payment_at' =>  $data[0]['payment_at'],   //payment_at支付成功時間--非必要
            'created_at' =>  $data[0]['created_at'],   //created_at訂單創建時間--必要
            'updated_at' =>  self::getDate()
        ];
        $orderID = $this->insertGetId($order);
        if(!empty($orderID)){
            $addDetails = true;
            for($i=0;$i<count($data);$i++){
                $product_specs[$i] = [];
                $productRelation = true;
                $product = true;
                if(!empty($data[$i]['product_relation_id'])){
                    $product_specs_value_id=ProductRelation::where('product_relation_id',$data[$i]['product_relation_id'])->first()['product_specs_value_id'];
                    $product_specs[$i] = ProductSpecsValue::whereIn('product_specs_value_id',explode('-',$product_specs_value_id))->get()->toArray();
                    if($data[$i]['product_type'] == 1){
                        $productRelation = ProductRelation::where('product_relation_id',$data[$i]['product_relation_id'])->decrement('stock',$data[$i]['product_number']);
                    }
                }
                $detailsInfo[$i] = [
                    'order_id' => $orderID,
                    'user_id' => $data[$i]['user_id'],
                    'product_id' => $data[$i]['product_id'],
                    'product_relation_id' => $data[$i]['product_relation_id'],
                    'product_specs' => json_encode($product_specs[$i]),
                    'product_name' => $data[$i]['product_name'],
                    'product_img' => $data[$i]['product_img'],
                    'product_number' => $data[$i]['product_number'],
                    'product_price' => $data[$i]['product_price'],
                    'product_money' => $data[$i]['product_money'],
                    'product_type' => $data[$i]['product_type'],
                    'logistics_status' => 2,
                    'created_at' => $data[0]['created_at'],
                    'updated_at' => self::getDate()
                ];
                $details = OrderDetails::insertGetId($detailsInfo[$i]);
                if($data[$i]['product_type'] == 1){
                    $product = Product::where('product_id',$data[$i]['product_id'])->decrement('product_stock',$data[$i]['product_number']);
                }
                $logisticsInfo[$i] = [
                    'details_id' => $details,
                    'user_id' => $data[$i]['user_id'],
                    'logistics_status' => 2,
                    'created_at' => self::getDate(),
                    'updated_at' => self::getDate()
                ];
                $logistics = OrderLogistics::insert($logisticsInfo[$i]);
                //添加訂單詳情快照-begin
                $Snapshot['details_id']=$details;
                $Coupon=new Coupon;
                $Product=new Product;
                $Snapshot['product_snapshot']=$Product->ProductSnapshot($data[$i]['product_id']);
                $User=new User;
                $Snapshot['user_snapshot']=$User->UserSnapshot($data[$i]['user_id']);
                $OrderSnapshot=new OrderSnapshot;
                $SnapshotInfo=$OrderSnapshot->addOrderSnapshot($Snapshot);
                //添加訂單詳情快照-end
                if( empty($details) || !$product || !$productRelation || !$logistics){
                    $addDetails = false;
                    break;
                }
            }
            if($addDetails){
                DB::commit();
                return $this->success(__('web.add_success'));
            }else{
                DB::rollBack();
                return $this->error(__('web.add_fail'));
            }
        }else{
            DB::rollBack();
            return $this->error(__('web.add_fail'));
        }
    }

    /**
     * 獲取訂單分析
     * @param $data
     * @param $language
     * @return array
     */
    public function getOrderAnalysisWeb($data,$language){
        $limit = $data['limit'];
        $page = ($data['page'] - 1) * $limit;

        $fieldName = 'sale_number';
        $sort = 'desc';
        $time = [];

        if(!empty($data['time'])){
            $time['start_time'] = $data['time'][0];
            $time['end_time'] = $data['time'][1];
        }
        if(!empty($data['sort'])){
            $sort = $data['sort'];
        }
        if(!empty($data['fieldName'])){
            $fieldName = $data['fieldName'];
        }

        $where[] = array('order.payment_status', '>=', 3);
        $where[] = array('order.order_status', '=', 1);
        $where[] = array('users.user_status', '=', 1);

        //查詢產品信息和 瀏覽量 和 收藏量 和 庫存
        $productInfo = Product::leftjoin('order_details','order_details.product_id','=','product.product_id')
            ->where('product.product_status','<>', -1)
            ->where('product.product_type','=', 1)
            ->where(function ($query) use($data){
                if(!empty($data['product_name'])){
                    $query->whereRaw('(concat(product.product_name,product.en_product_name) like "%' . $data['product_name'] . '%")');
                }
            })
            ->where(function ($query) use ($time) {
                if ($time != null)
                    $query->whereBetween('order_details.created_at', $time);
            })
            ->select('product.product_id','product.'.$language.'product_name as product_name','product.product_stock','product.product_img','product.product_price','product.browse_number')
            ->withCount(['userCollect as user_collect_number'=>function($query){
                $query->select(DB::raw("COUNT(collect_id)"));
            }])
            ->groupBy("product.product_id")
            ->get()->toArray();

        //该商品销售总额和銷售總量
        if(!empty($productInfo)){
            foreach ($productInfo as $key => $value) {
                $info[$key] = OrderDetails::join('users','users.user_id','=','order_details.user_id')
                    ->join('order','order_details.order_id','=','order.order_id')
                    ->where($where)
                    ->where('order_details.product_id', $productInfo[$key]['product_id'])
                    ->where(function ($query) use ($time) {
                        if ($time != null)
                            $query->whereBetween('order_details.created_at', $time);
                    })
                    ->select('order_details.details_id',DB::raw('SUM(order_details.product_money) as product_money'),DB::raw('SUM(order_details.product_number) as product_number'))
                    ->groupBy("order_details.product_id")
                    ->first();
                $productInfo[$key]['sale_money'] = empty(json_decode(json_encode($info[$key], true),true)['product_money']) ? 0 : json_decode(json_encode($info[$key], true),true)['product_money'];
                $productInfo[$key]['sale_number'] = empty(json_decode(json_encode($info[$key], true),true)['product_number']) ? 0 : json_decode(json_encode($info[$key], true),true)['product_number'];
            }
        }

        $last_names = array_column($productInfo,$fieldName);
        if($sort == 'asc'){
            array_multisort($last_names,SORT_ASC,$productInfo);
        }else if($sort == 'desc'){
            array_multisort($last_names,SORT_DESC,$productInfo);
        }

        $datas['data'] = array_slice($productInfo,$page,$limit);
        $datas['count'] = count($productInfo);

        return $this->success(__('web.success'),$datas);

    }

    /**
     * 獲取銷售方向分析
     * @param $data
     * @param $language
     * @return array
     */
    public function getSalesDirectionWeb($data,$language){
        $threeMonths = Carbon::now()->subMonths(3)->format('Y-m-d');  //三个月前的时间
        $where[] = array('order.payment_status', '>=', 3);
        $where[] = array('order.order_status', '=', 1);
        $where[] = array('users.user_status', '=', 1);
        $where[] = array('product.product_status', '=', 1);
        $detailsData = OrderDetails::join('users','users.user_id','=','order_details.user_id')
            ->join('order','order_details.order_id','=','order.order_id')
            ->join('product','order_details.product_id','=','product.product_id')
            ->join('product_sort','product_sort.product_sort_id','=','product.product_sort_id')
            ->where($where)
            ->whereNotNull('order.payment_at')
            ->whereBetween('order.payment_at',[$threeMonths,self::getDate()])
            ->select('product.'.$language.'product_name as product_name','product_sort.'.$language.'product_sort_name as product_sort_name',
                DB::raw('SUM(order_details.product_number) as product_number'),DB::raw('DATE(order.payment_at) as payment_date'),
                DB::raw('SUM(order_details.product_money) as money'))
            ->groupBy('payment_date','order_details.product_id')
            ->orderBy('payment_date')
            ->get()->toArray();

        $datas['saleData'] = $detailsData;
        $datas['totalSales'] = Collection::make($detailsData)
            ->groupBy('product_sort_name') // 按 product_sort_name 分组
            ->map(function ($item, $productName) {
                // 计算每个组的 product_number 的总和
                $totalNumber = $item->sum('product_number');

                // 返回一个包含 product_name 和 product_number 总和的数组
                return [
                    'product_sort_name' => $productName,
                    'sort_number' => $totalNumber,
                ];
            })
            ->sortByDesc('product_number')
            ->take(3)
            ->values() // 重置键名
            ->all();

        return $this->success(__('web.success'),$datas);
    }

/**********************************************************api****************************************************************************/
    /**
     * 獲取訂單列表
     * @param $data
     * @return mixed
     */
    public function getOrderListApi($data){
        $limit = empty($data['limit']) ? 10 : $data['limit'];
        $page =  ( $data['page'] - 1 ) * $limit;
        $where[] = array('users.user_status', '<>', -1);
        $where[] = array('order.order_status', '<>', -1);
        $where[] = array('order.user_id', '=', $data['user_id']);
        // 支付类型：1：立即支付，2：預約到店查看
        if(!empty($data['payment_type'])){
            $where['order.payment_type'] = $data['payment_type'];
        }
        // 訂單類型  1產品訂單  2預約訂單
        if(!empty($data['indent_type'])){
            $where['order.indent_type'] = $data['indent_type'];
        }
        $effects=array();
        OrderDetails::$modify = true;
        OrderSnapshot::$modify = true;
        $info= $this->with(['OrderDetails'=>function($query){
            $query->with('OrderLogistics')->with('OrderSnapshot')->select('*');
            }]) ->join('users','users.user_id','=','order.user_id')->where($where)->select('order.*')
            ->orderBy('order.created_at', 'desc')->paginate($limit , $page);
        $effects=$info->items();
        foreach ($effects as $key => $value) {
            if(empty($effects[$key]['order_code'])){
                $effects[$key]['order_code']=$this->getQRCode($effects[$key]['order_no']);
            }
        }
        $results['count']=$info->count();
        $results['currentPage']=$info->currentPage();
        $results['limit']=$info->perPage();
        $results['lastPage']=$info->lastPage();
        $results['data']=$effects;
        if(!empty($effects)){
             // $this->LogInfo('獲取收貨地址列表' , $effects , 'getUserAddress' , true);//开启日志记录
            return $this->success( __('api.list_success'), $results);
        }else{
            return $this->success( __('api.list_null'), $results);
        }
    }



    /**
     * 獲取訂單詳情
     * @param $data
     * @return mixed
     */
    public function getOrderDetailsApi($data){
        $where[] = array('users.user_status', '<>', -1);
        $where[] = array('order.order_status', '<>', -1);
        $where[] = array('order.user_id', '=', $data['user_id']);
        $where[] = array('order.order_id', '=', $data['order_id']);
        $effects=array();
        OrderDetails::$modify = true;
        OrderSnapshot::$modify = true;
        $effects= $this->with(['OrderDetails'=>function($query){
            $query->with('OrderLogistics')->with('OrderSnapshot')->select('*');
            }]) ->join('users','users.user_id','=','order.user_id')->where($where)->select('order.*')->first();
            if(empty($effects['order_code'])){
                $effects['order_code']=$this->getQRCode($effects['order_no']);
            }
        if(!empty($effects)){
             // $this->LogInfo('獲取收貨地址列表' , $effects , 'getUserAddress' , true);//开启日志记录
            return $this->success( __('api.list_success'), $effects);
        }else{
            return $this->success( __('api.list_null'), $effects);
        }
    }



    /**
     * 确认收貨
     * @param $orderID
     * @return array
     */
    public function ConfirmReceipt($data){
        $effects = $this->where('order_id',$data['order_id'])->where('user_id',$data['user_id'])->update(['payment_status'=>5]);
        $languagenow = $this->language == "en_" ? "en" : "cn";
        if($effects){
            $info = $this->where('order_id',$data['order_id'])->select('order_no','delivery_mail')->first();
            $cn_content = '訂單：'.$info['order_no'].',已經确认收貨！';
            $en_content = 'Order:'.$info['order_no'].' , receipt has been confirmed!';
            if($languagenow == "en" ){
                $EmailInfo['Message']=$en_content;
                @self::pushOrderMessage($data['order_id'],$cn_content,$en_content,$languagenow);
            }else{
                $EmailInfo['Message']=$cn_content;
                @self::pushOrderMessage($data['order_id'],$cn_content,$en_content,$languagenow);
            }
            $this->OrderMessage( $data['user_id'] ,$cn_content , $en_content );
            $email=new MailController();
            $EmailInfo['Email']=$info['delivery_mail'];
            $email->MessageEmails($EmailInfo);
            return $this->success(__('api.edit_success'));
        }else{
            return $this->error(__('api.edit_fail'));
        }
    }


    /**
     * 刪除訂單
     * @param $orderID
     * @return array
     */
    public function deleteOrderApi($data){
        DB::beginTransaction();
        $updateDetails = OrderDetails::where('order_id',$data['order_id'])->where('user_id',$data['user_id'])->update(['details_status' => -1]);
        $updateOrder = $this->where('order_id',$data['order_id'])->where('user_id',$data['user_id'])->update(['order_status'=>-1]);
        if($updateDetails && $updateOrder){
            $info = $this->where('order_id',$data['order_id'])->select('order_no')->first();
            $content = '訂單：'.$info['order_no'].', 已經被刪除!!';
            $en_content = 'Order:'.$info['order_no'].' , has been deleted !!';
            $this->OrderMessage($data['user_id'] ,$content , $en_content );
            DB::commit();
            return $this->success(__('api.delete_success'));
        }else{
            DB::rollBack();
            return $this->error(__('api.delete_fail'));
        }
    }




/**************************************************common(api和admin共用)*****************************************************************/
    /**
     * @param $data
     * @return array
     * 添加系統消息
     */
    public function OrderMessage($user_id,$content,$en_content){
        DB::beginTransaction();
        try {
            $info['user_id'] = $user_id;
            $info['system_type'] = 3;//消息類型  1,服務 2,產品  3,系統 4,其他
            $info['system_content'] = $content;
            $info['en_system_content'] = $en_content;
            $info['is_read'] = 1;
            $info['created_at'] = date('Y-m-d H:i:s');
            $info['updated_at'] = date('Y-m-d H:i:s');
            $effects = $this->insert($info);
            if(!empty($effects)){
                // $this->LogInfo('多语言日志' , $results , 'lang' , true);//开启日志记录
                DB::commit();
                return true;
            }else{
                DB::rollBack();
                return false;
            }
        }catch (\Exception $e) {
            DB::rollBack();
            return false;
        }
    }


/**********************************************************支付相关调用**********************************************************************/

    /**
     * @return string
     * 生成訂單號
     */
    public function getOrderNumber(){
        list($msec, $sec) = explode(' ', microtime());
        $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
        return $msectime;
    }


    /**
     * @param $token
     * @param $data
     * @return mixed
     * 生成訂單信息(api)支付
     */
    public function generateOrder($data){
        DB::beginTransaction();
        try {
            //生成订单号
            $orders['order_no'] = self::getOrderNumber();
             //生成订单二维码
            $order_no=(string)$orders['order_no'];
            $orders['order_code'] = $this->getQRCode($order_no);
            //用户id
            $orders['user_id'] = $data['user_id'];
            //優惠券id
            $orders['coupon_id'] = $data['coupon_id'];
            //產品原價
            $orders['original_cost'] = $data['original_cost'];
            //產品支付金额
            $orders['order_money']= empty($data['order_money']) ? 0 : $data['order_money'];
            //產品運費
            $orders['freight_price']= empty($data['freight_price']) ? 0 : $data['freight_price'];
            //预约到店金额
            $orders['booking_price']= empty($data['booking_price']) ? 0 : $data['booking_price'];
            //優惠金额
            $orders['coupon_money'] = empty($data['coupon_money']) ? 0 : $data['coupon_money'];
            // 支付类型：1：立即支付，2：預約到店查看
            $orders['payment_type']=empty($data['payment_type']) ? 1 : $data['payment_type'];
            // 支付方式: 1：paypal  2：Stripe，3：錢包 ，4：其他支付（上傳支付圖片） 5:線下支付
            $orders['payment_mode']=empty($data['payment_mode'] )? 1 : $data['payment_mode'];
            // 訂單類型：1：線上訂單，2：線下訂單
            $orders['order_type']=empty($data['order_type']) ? 1 : $data['order_type'];
            // 訂單類型：1：產品訂單，2：預約訂單
            $orders['indent_type']=empty($data['indent_type']) ? 1 : $data['indent_type'];
            // 取货方式：1：商家发货，2：自取
            $orders['receiving_type']=empty($data['receiving_type']) ? 1 : $data['receiving_type'];
            // 收货地址-区域
            $orders['delivery_area']=empty($data['delivery_area']) ? '': $data['delivery_area'];
            // 收货地址-地址
            $orders['delivery_address']=empty($data['delivery_address']) ? '': $data['delivery_address'];
            // 收货地址-姓名
            $orders['delivery_name']=empty($data['delivery_name']) ? '': $data['delivery_name'];
            // 收货地址-电话
            $orders['delivery_phone']=empty($data['delivery_phone']) ? '': $data['delivery_phone'];
            // 收货地址-邮件
            $orders['delivery_mail']=empty($data['delivery_mail']) ? '': $data['delivery_mail'];
            // 訂單预约时间
            $orders['order_time']=empty($data['order_time']) ? '': $data['order_time'];
            // 訂單预约人数
            $orders['order_num']=empty($data['order_num']) ? '': $data['order_num'];
            // 訂單备注
            $orders['order_remark']=empty($data['order_remark']) ? '': $data['order_remark'];
            // 支付状态：1：待支付2：已支付3：已收货4：已评论 5：已取消
            $orders['payment_status'] = 1;
            // 退货状态：0：不可退款1：可退款2：退款中3：已退款
            $orders['return_status'] = 0;
            // 推送状态：1：未推送 2：已推送
            $orders['push_state'] = 1;
            // 郵件發送狀態 ： 1：未發送  2：已發送
            $orders['mail_state'] = 1;
            // 状态(1可用，2禁用,-1删除)
            $orders['order_status'] = 1;
            // 创建时间
            $orders['created_at'] = date('Y-m-d H:i:s');
            // 更新时间
            $orders['updated_at'] = date('Y-m-d H:i:s');
            //添加订单
            $OrderId = $this->insertGetId($orders);
            if(!empty($OrderId)){
                // $this->LogInfo('添加收貨地址' , $effects , 'addUserAddress' , true);//开启日志记录
                DB::commit();   return $OrderId;
            }else{
                DB::rollBack();   return false;
            }
        }catch (\Exception $e) {
            DB::rollBack();   return  $e->getMessage();
        }
    }



    /**
     * @param $token
     * @param $data
     * @return string
     * 添加訂單產品詳情(api)支付
     */
    public function setDetailsOrder($data){
        DB::beginTransaction();
        $ProductInfo=$data['ProductInfo'];
        try {
            foreach ($ProductInfo as $key => $value) {
                //查詢規格
                $product_specs=[];
                if(!empty($ProductInfo[$key]['product_relation_id'])){
                    $product_specs_value_id=ProductRelation::where('product_relation_id',$ProductInfo[$key]['product_relation_id'])->first()['product_specs_value_id'];
                    $product_specs = ProductSpecsValue::whereIn('product_specs_value_id',explode('-',$product_specs_value_id))->get()->toArray();
                    // $this->LogInfo('產品規格' , $product_specs , 'product_specs' , true);//开启日志记录
                }
                //發貨方式  receiving_type  自取沒有物流
               $logistics_status= $data['receiving_type']==2 ? 1 : 0;
                $info = [
                    'order_id'=>$data['order_id'],
                    'user_id' =>$data['user_id'],
                    'product_id' => $ProductInfo[$key]['product_id'],
                    'product_relation_id' => $ProductInfo[$key]['product_relation_id'],
                    'product_specs' =>json_encode($product_specs),
                    'product_name' => $ProductInfo[$key]['product_name'],
                    'product_img' => $ProductInfo[$key]['product_img'],
                    'product_number' => $ProductInfo[$key]['product_number'],
                    'product_price' => $ProductInfo[$key]['product_price'],
                    'logistics_status' => $logistics_status,
                    'product_money' => $ProductInfo[$key]['product_number']*$ProductInfo[$key]['product_price'],
                    'product_type' => $ProductInfo[$key]['product_type'],
                    'details_remark' => $ProductInfo[$key]['details_remark'],
                    'details_status' => 1,
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s')
                ];
                $details[$key] = $this->from('order_details')->insertGetId($info);
                //添加訂單詳情快照-begin
                $Snapshot['details_id']=$details[$key];
                $Coupon=new Coupon;
                $couponinfo=$this->where('order_id',$data['order_id'])->select('coupon_id')->first()->toArray();
                if(!empty($couponinfo['coupon_id'])){
                    $Snapshot['coupon_snapshot']=$Coupon->CouponSnapshot($couponinfo['coupon_id']);
                }else{
                    $Snapshot['coupon_snapshot']='';
                }
                $Product=new Product;
                $Snapshot['product_snapshot']=$Product->ProductSnapshot($ProductInfo[$key]['product_id']);
                $User=new User;
                $Snapshot['user_snapshot']=$User->UserSnapshot($data['user_id']);
                $OrderSnapshot=new OrderSnapshot;
                $SnapshotInfo=$OrderSnapshot->addOrderSnapshot($Snapshot);
                //添加訂單詳情快照-end
                //添加訂單詳情物流-begin
                $OrderLogistics=new OrderLogistics;
                $SnapshotInfo=$OrderLogistics->addOrderLogistics($data['user_id'],$Snapshot['details_id']);
                //添加訂單詳情物流-end
            }
            if(!empty($SnapshotInfo)){
                // $this->LogInfo('添加收貨地址' , $effects , 'addUserAddress' , true);//开启日志记录
                DB::commit();   return implode(',',$details);
            }else{
                DB::rollBack();   return false;
            }
        }catch (\Exception $e) {
            DB::rollBack();   return  $e->getMessage();
        }
    }















/**************************************************END***********************************************************/

}
